﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Diagnostics;
using Microsoft.Win32;
using System.IO;


namespace XBoshi.SecurityCommon
{
   public  class MachineNumber
    {
        

        private static Register r = new Register();
        private LicenseClass license = null;



        public LicenseClass GetLicense()
        {
            return license;
   
        }


        /// <summary>
        /// 获取机器注册特征码
        /// </summary>
        /// <returns></returns>
        public static String GetMachineCode(String p_ApplicationPath) {
            r.ApplicationPath = p_ApplicationPath;
            String strCPU =Convert.ToBase64String(Encoding.Default.GetBytes(r.GetCpuInfo()));
            String HD = Convert.ToBase64String(Encoding.Default.GetBytes(r.GetHDid())); ;
            String HDSize = Convert.ToBase64String(Encoding.Default.GetBytes(r.GetHDSize())) ;
            String NetWork = Convert.ToBase64String(Encoding.Default.GetBytes(r.GetMoAddress ()));
            ApplicationPath =p_ApplicationPath;

            String MachineCode = strCPU.Substring(0,2)  + HD.Substring(4,2)  + HDSize.Substring(8,2)  + NetWork.Substring(12,2) ;
            Debug.WriteLine(MachineCode );  
            //对特征码进行加密
           // MachineCode = MD5Class.MyDESCrypto(MachineCode, Encoding.Default.GetBytes("11111111"),Encoding.Default.GetBytes("22222222"));
           //var Ormp=MD5Class.MyDESCryptoDe(MachineCode ,Encoding.Default.GetBytes("11111111"),Encoding.Default.GetBytes("22222222"));
           //Debug.WriteLine(Ormp);

           return MachineCode.ToUpper() ;
        }

        public static String GetMachineNumber(String p_ApplicationPath)
        {
            String code = GetMachineCode(p_ApplicationPath);
            String number = "";
            foreach (var c in code) {
                number += String.Format("{0}", (int)c);             
            }
            return number;
        }

        public static String GetMachineCodeByNum(String machineNum)
        {
            String MachineCode = "";
            for (int i = 0; i < machineNum.Length-1 ; i += 2) { 
                int c=Int16.Parse(machineNum.Substring(i,2));
                MachineCode += String.Format("{0}", (char)c);          
            }
            return MachineCode;
        }



        public static  String ApplicationPath { set; get; }

        public static string GetDiskVolumeSerialNumber()
        {
            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"d:\"");
            disk.Get();
            return disk.GetPropertyValue("VolumeSerialNumber").ToString();
        }
 
        //获得CPU的序列号
        public static string getCpu()
        {
            string strCpu = null;
            ManagementClass myCpu = new ManagementClass("win32_Processor");
            ManagementObjectCollection myCpuConnection = myCpu.GetInstances();
            foreach (ManagementObject myObject in myCpuConnection)
            {
                strCpu = myObject.Properties["Processorid"].Value.ToString();
                break;
            }
            return strCpu;
        }
        //生成机器码
        public static string getMNum()
        {
            string strNum = getCpu() + GetDiskVolumeSerialNumber();//获得24位Cpu和硬盘序列号
            string strMNum = strNum.Substring(0, 24);//从生成的字符串中取出前24个字符做为机器码
            return strMNum;
        }
        public static int[] intCode = new int[127];//存储密钥
        public static int[] intNumber = new int[25];//存机器码的Ascii值
        public static char[] Charcode = new char[25];//存储机器码字

        public static void setIntCode()//给数组赋值小于10的数
        {
            for (int i = 1; i < intCode.Length; i++)
            {
                intCode[i] = i % 9;
            }
        }
 
//第二步。根据机器码 生成注册码 
        //生成注册码      
 
       public static string getRNum()
        {
            setIntCode();//初始化127位数组
            for (int i = 1; i < Charcode.Length; i++)//把机器码存入数组中
            {
                Charcode[i] = Convert.ToChar(getMNum().Substring(i - 1, 1));
            }
            for (int j = 1; j < intNumber.Length; j++)//把字符的ASCII值存入一个整数组中。
            {
                intNumber[j] = intCode[Convert.ToInt32(Charcode[j])] + Convert.ToInt32(Charcode[j]);
            }
            string strAsciiName = "";//用于存储注册码
            for (int j = 1; j < intNumber.Length; j++)
            {
                if (intNumber[j] >= 48 && intNumber[j] <= 57)//判断字符ASCII值是否0－9之间
                {
                    strAsciiName += Convert.ToChar(intNumber[j]).ToString();
                }
                else if (intNumber[j] >= 65 && intNumber[j] <= 90)//判断字符ASCII值是否A－Z之间
                {
                    strAsciiName += Convert.ToChar(intNumber[j]).ToString();
                }
                else if (intNumber[j] >= 97 && intNumber[j] <= 122)//判断字符ASCII值是否a－z之间
                {
                    strAsciiName += Convert.ToChar(intNumber[j]).ToString();
                }
                else//判断字符ASCII值不在以上范围内
                {
                    if (intNumber[j] > 122)//判断字符ASCII值是否大于z
                    {
                        strAsciiName += Convert.ToChar(intNumber[j] - 10).ToString();
                    }
                    else
                    {
                        strAsciiName += Convert.ToChar(intNumber[j] - 9).ToString();
                    }
                }
            }
            return strAsciiName;
        }
 
//第三步。检查注册状况，若没有注册，可自定义试用       
 
/// <summary>
        /// 检查注册
        /// </summary>
       public static LicenseClass CheckRegist(LicenseClass lc)
        {
            lc = GetLicencesFromRegistry();
            if (lc.isTempLincese == false) {
                return lc;
            }
            //更新一次剩余次数
            String strLc = (String)Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\Xboshi\\XBoshiGFS", "RemainTimes", "");
            MachineNumber mn = new MachineNumber(); 
            try
            {
                long remainTimes = mn.DecodeRemainTimes(strLc);
                remainTimes = remainTimes - 1;
                lc.remainTimes = remainTimes;
                String strRemainTimes = mn.EncodeRemainTimes(lc.remainTimes);
                Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Xboshi\\XBoshiGFS", "RemainTimes", strRemainTimes, RegistryValueKind.String);
            }
            catch {
                lc.remainTimes = -1;
                return lc;
            
            }

           return lc;
        }


        public  long GetRemainTime() {

            return 1;
        
        }


        private static String strMachineCode;




        private String EncodeRemainTimes(long remainTimes) {

            //序列话数据

            String data = String.Format("{0}", remainTimes);
            data=data.PadLeft(8, '0'); 

            byte[] keys = new MD5Class().GetKeys(0);
            String firstDecrytonResult = MD5Class.MyDESCrypto(data, keys, null);
            return firstDecrytonResult;
        }
        private long DecodeRemainTimes(String securyData)
        {
            byte[] keys = new MD5Class().GetKeys(0);
            String firstDecrytonResult = MD5Class.MyDESCryptoDe(securyData, keys, null);
            long l = long.Parse(firstDecrytonResult); 
            return l;
        }


        private String  GetSecurtyData(LicenseClass lc) {

            int keyType = ((int)lc.machinCode.Substring(0, 1).ToCharArray().FirstOrDefault()) % 3;
            String LicenseInfo = lc.GetXmlSerializer();

            //序列话数据
            byte[] keys = new MD5Class().GetKeys(keyType);
            String firstDecrytonResult = MD5Class.MyDESCrypto(LicenseInfo, keys, null);
            String MachiCode = MachineNumber.GetMachineCodeByNum(lc.machinCode);
            keys = Encoding.ASCII.GetBytes(MachiCode);
            String SecondDecrytonResult = MD5Class.MyDESCrypto(firstDecrytonResult, keys, null);
            return  SecondDecrytonResult;
        }

        private LicenseClass DecodeLicenseData(String SecurData) {
            LicenseClass lc=new LicenseClass ();
            //进行解密
            String MachiCode = MachineNumber.GetMachineCode(MachineNumber.ApplicationPath);
            byte[] keys = Encoding.ASCII.GetBytes(MachiCode);
            String SecondDecrytonResult = MD5Class.MyDESCryptoDe(SecurData, keys, null);
            //
            int keyType = ((int)MachineNumber.GetMachineNumber(MachineNumber.ApplicationPath).Substring(0, 1).ToCharArray().FirstOrDefault()) % 3;
            keys = new MD5Class().GetKeys(keyType);
            String firstDecrytonResult = MD5Class.MyDESCryptoDe(SecondDecrytonResult, keys, null);
            lc = lc.ParaseXmlSerializer(firstDecrytonResult);  
            return lc;
        }


           public static void  Regist(String regCode){
               MachineNumber mn = new MachineNumber();
               String strLc = regCode;
               try
               {
                   LicenseClass lc = mn.DecodeLicenseData(strLc); ;
                   strLc = mn.GetSecurtyData(lc);
                   String strRemainTimes = mn.EncodeRemainTimes(lc.usingtimes);
                   Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Xboshi\\XBoshiGFS", "License", strLc, RegistryValueKind.String);
                   Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Xboshi\\XBoshiGFS", "RemainTimes", strRemainTimes, RegistryValueKind.String);
               }
               catch { 
               
               
               }
 
           } 


        private static LicenseClass GetLicencesFromRegistry() {
            MachineNumber mn = new MachineNumber();
            String strLc = null;
            LicenseClass lc =mn.CreateTempLicenseClass(); 

            try
            {
                strLc = (String)Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\Xboshi\\XBoshiGFS", "License", "");
                if (String.IsNullOrWhiteSpace(strLc)) {
                    throw new Exception("11111"); 
                }
               var  tmplc = mn.DecodeLicenseData(strLc);  

            }
            catch(Exception ex)
            {
                strLc = mn.GetSecurtyData(lc);
                String strRemainTimes = mn.EncodeRemainTimes(lc.usingtimes);
                Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Xboshi\\XBoshiGFS", "License", strLc, RegistryValueKind.String);
                Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Xboshi\\XBoshiGFS", "RemainTimes", strRemainTimes, RegistryValueKind.String);
            }
            lc = mn.DecodeLicenseData(strLc);  
            return lc;
        
        }


        public LicenseClass CreateTempLicenseClass() {
            LicenseClass lc = new LicenseClass();
            lc.uid = Guid.NewGuid().ToString();
            lc.usingtimes = 100;
            lc.validDate = DateTime.Now.AddYears(1);
            lc.isTempLincese = true;
            lc.machinCode = MachineNumber.GetMachineNumber(MachineNumber.ApplicationPath);
            return lc; 
        }


        private int CalcRemainTimes() {
            FileInfo f = new FileInfo(MachineNumber.ApplicationPath);
            //  f.LastWriteTime-DateTime.Now   




            return 0;
        }


        /// <summary>
        /// 验证试用次数
        /// </summary>
        private static void thCheckRegist2()
        {
            //MessageBox.Show("您现在使用的是试用版，该软件可以免费试用3000000次！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            //Int32 tLong;
            //try
            //{
            //    tLong = (Int32)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\angel", "UseTimes", 0);
            //    MessageBox.Show("感谢您已使用了" + tLong + "次", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            //}
            //catch
            //{
            //    Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\angel", "UseTimes", 0, RegistryValueKind.DWord);
            //    MessageBox.Show("欢迎新用户使用本软件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            //}
            //tLong = (Int32)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\angel", "UseTimes", 0);
            //if (tLong < 3000000)
            //{
            //    int Times = tLong + 1;
            //    Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\angel", "UseTimes", Times);
            //}
            //else
            //{
            //    MessageBox.Show("试用次数已到", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            //    Application.Exit();
            //}
        }

    }
}
